
/*
* @version: 1.0
* @Author: zhanggq
* @Date: 2023-01-03 10:01:00
* @LastEditTime: 2023-01-03 16:39:30
* @Description: 映射关系管理
*/

#ifndef   __MAPING_RELATION_MANAGER__
#define   __MAPING_RELATION_MANAGER__

#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <unordered_map>
#include "DataCenterManager.h"
#include "../../../include/protocol_engine_config.h"
#include "../../../include/DCData.h"
#include "../../common/include/CThreadNotify.h"
#include "CConfigManager.h"


//104下行命令
typedef struct __down_cmd__
{
    int64_t  dev_id;
    int64_t  cmd_id;
    __down_cmd__(){
        dev_id = 0;
        cmd_id = 0;
    }
}ST_IEC104_DOWN_CMD;

//冻结数据点信息
typedef struct __frozen_pt_info
{
    int64_t     point_id;
    int         data_type;
}ST_FROZEN_PTINFO;

typedef std::unordered_map<std::string, ST_DEV_GUID>  T_DEVADDR_DEVGUID_TYPE;
typedef std::unordered_map<std::string, ST_DEV_GUID>  T_GUID_DEVGUID_TYPE;

typedef std::unordered_map<std::string, ST_104_INFO_OBJECT>  T_DC_NAME_104INFO_OBJ;         //<数据中心模型属性名，104信息对象>
typedef std::unordered_map<std::string, T_DC_NAME_104INFO_OBJ> T_DC_DEVGUID_104INFO_OBJ;    //<数据中心dev,<数据中心模型属性名，104信息对象>>
typedef std::unordered_map<int,ST_IEC104_DOWN_CMD> T_IEC104_DOWN_CMD;                       //<信息对象地址，下行设备和命令ID>
typedef std::unordered_map<int64_t, std::unordered_map<int64_t, double>>  T_IEC104_PT_DEADZONE;   //iec104死区<devi_id,<point_id,deadzone>>


class CMappingRelationManager
{
public:
    CMappingRelationManager();
    ~CMappingRelationManager();

    static CMappingRelationManager*    getInstance();
    void  init(std::shared_ptr<CConfigManager> cm);


    void build_dc_iec104_relevance(std::list<ST_SINGLE_MODEL_INFO>& lstModelsInfo, std::list<ST_REGISTER_MODEL_INFO>& lstRegisterRelation);
    std::shared_ptr<ST_104_INFO_OBJECT> get_iec104Obj_with_dev_ptname(std::string& dev,std::string& ptname);

    void build_iec104_down_relevance();
    std::shared_ptr<ST_IEC104_DOWN_CMD>  get_dev_cmd_withobjaddr(int obj_addr);

    void  build_iec104_deadzonemp();
    double get_point_deadzone(int64_t dev_id,int64_t point_id);

    void build_points_relation();
    std::string get_point_name(int64_t dev_id, int64_t  point_id);
    std::shared_ptr<ST_FROZEN_PTINFO>  get_point_info(std::string& name);    //根据点名称查询点信息---目前冻结数据用

    //通过点名称得到命令信息
    std::shared_ptr<MODBUS_COMMAND> modbus_get_cmd_info(std::string& cmd_name);
    std::shared_ptr<DLT645_COMMAND> dlt645_get_cmd_info(std::string& cmd_name);
    template<typename T>
    std::shared_ptr<T> get_cmd_info(std::string& dev, std::string& cmd_name){
        auto  pstDevGuid = DataCenterManager::getInstance()->get_devguid_withdev(dev);
        if (0 >= pstDevGuid->id ){
            return nullptr;
        }

        auto  term_dev = c_cm->get_terminal_device(pstDevGuid->id);
        if (nullptr == term_dev) {
            return nullptr;
        }
        auto proto = c_cm->get_protocol_rule(term_dev->protocol_id);
        if (proto->protocol_type == 1) {//modbus
            return modbus_get_cmd_info(cmd_name);
        }
        else if (proto->protocol_type == 2){ //dlt645
            return dlt645_get_cmd_info(cmd_name);
        }
        
        return nullptr;
    }

public:
    CThreadNotify  m_thdnotify_iec104obj;
    CThreadNotify  m_thdnotify_devguid1;
    CThreadNotify  m_thdnotify_devguid2;

private:
    static  CMappingRelationManager c_mapingRelationMana;
    std::shared_ptr<CConfigManager> c_cm;
        
    void  append_dev_datapt(std::string dev, std::vector<std::string> data_names, IEC104_INFO_OBJECT_PTR iec104objs);
    std::shared_ptr<ST_DEV_GUID> get_devguid_with_devaddr(std::string& addr);
    std::string get_comp_addr(std::string & addr, int64_t pid, bool bfrozen);

protected:

    T_DC_DEVGUID_104INFO_OBJ  c_dc_dev_104InfoObjs;
    T_IEC104_DOWN_CMD         c_iec104_down_cmds;

    T_IEC104_PT_DEADZONE      c_iec104_pts_deadzone;

    std::unordered_map<int64_t, std::string>     c_modbus_points;
    std::unordered_map<int64_t, std::string>     c_dlt645_points;
    std::unordered_map<int64_t, std::string>     c_dlt698_points;
    std::unordered_map<std::string, ST_FROZEN_PTINFO>   c_frozen_ptinfo;

};

#endif
